home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 2
/
AACD 2.iso
/
AACD
/
Utilities
/
XPK
/
xpk_Source
/
libraries
/
RLEN
/
xpkRLEN.c
< prev
Wrap
C/C++ Source or Header
|
1998-11-09
|
3KB
|
131 lines
#include <xpk/xpksub.h>
#ifdef __MAXON__
#define __asm
#endif
struct XpkMode RlenMode =
{
NULL, /* next */
100, /* upto */
XPKMF_A3000SPEED, /* flags */
0, /* packmem */
0, /* unpackmem */
140, /* packspeed, K / sec */
1043, /* unpackspeed, K / sec */
45, /* ratio, *0.1 % */
0, /* reserved */
"normal" /* description */
};
static struct XpkInfo RlenInfo =
{
1, /* info version */
1, /* lib version */
0, /* master vers */
0, /* pad */
"RLEN", /* short name */
"Run Length", /* long name */
"Fast and simple compression usable for simple data", /* description*/
0x524C454E, /* 4 letter ID */
XPKIF_PK_CHUNK | /* flags */
XPKIF_UP_CHUNK,
0x7fffffff, /* max in chunk */
0, /* min in chunk */
0x4004, /* def in chunk */
NULL, /* pk message */
NULL, /* up message */
NULL, /* pk past msg */
NULL, /* up past msg */
50, /* def mode */
0, /* pad */
&RlenMode /* modes */
};
/*
* Returns an info structure about our packer
*/
#ifdef __cplusplus
extern "C"
#endif
struct XpkInfo * __asm XpksPackerInfo(void)
{
return &RlenInfo;
}
/*
* Pack a chunk
*/
#ifdef __cplusplus
extern "C"
#endif
LONG __asm XpksPackChunk(register __a0 struct XpkSubParams *xpar)
{
UBYTE *get = xpar->xsp_InBuf, *start = xpar->xsp_InBuf;
UBYTE *end = get + xpar->xsp_InLen, *put = xpar->xsp_OutBuf;
UBYTE *wend = put + xpar->xsp_OutBufLen;
LONG run, i;
for(;;)
{
run = get[0] == get[1] && get[1] == get[2];
if(put + (get - start) + 4 > wend)
return XPKERR_EXPANSION;
if(run || get - start == 127 || get == end)
{ /* write uncompressed */
if(get - start)
{
*put++ = get - start;
for(i = get - start; i > 0; i--)
*put++ = *start++;
}
if(get == end)
{
*put++ = 0;
break;
}
start = get;
}
if(run)
{ /* write compressed */
for(i = 3; get + i < end && get[i - 1] == get[i] && i < 127; i++);
*put++ = -i;
*put++ = get[0];
get += i;
start = get;
}
else
get++;
}
xpar->xsp_OutLen = put - (UBYTE *) xpar->xsp_OutBuf;
return 0;
}
#ifdef __cplusplus
extern "C"
#endif
LONG __asm XpksUnpackChunk(register __a0 struct XpkSubParams *xpar)
{
UBYTE *get = xpar->xsp_InBuf, *put = xpar->xsp_OutBuf, v;
LONG i;
while(i = (BYTE) *get++)
if(i > 0)
for(; i > 0; i--)
*put++ = *get++;
else
for(i = -i, v = *get++; i > 0; i--)
*put++ = v;
return 0;
}